<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>layer5</title>
  <script type="text/javascript">
    (function () {
      var b = document.createElement("meta");
      b.setAttribute("name", "viewport");
      var c = window.devicePixelRatio,
        a = c ? 1 / c : 1;
      window.screen.availWidth == document.documentElement.offsetWidth && (c = a = 1);
      document.documentElement.setAttribute("data-dpr", c || 1);
      window.navigator.userAgent.match(/android/i) ? b.setAttribute("content", "width=device-width, initial-scale=" +
        a + ", maximum-scale=" + a + ", minimum-scale=" + a + ", user-scalable=no, viewport-fit=cover") : b.setAttribute(
        "content", "initial-scale=" + a + ", maximum-scale=" + a + ", minimum-scale=" + a +
        ", user-scalable=no, viewport-fit=cover");
      document.head.appendChild(b)
    })();
  </script>
  <script type="text/javascript">
    var dpr = document.documentElement.getAttribute("data-dpr") || 1,
      width = document.documentElement.offsetWidth,
      fontSize = 100 / 750 * width;
    document.querySelector("html").style.fontSize = fontSize + "px";
    window.addEventListener("resize", function () {
      var a = 100 / 750 * document.querySelector("html").offsetWidth;
      document.querySelector("html").style.fontSize = a + "px"
    });
  </script>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <div class="box">
    <h1>layer弹层阻止超出滚动事件,js用touchmove模拟移动端的滚动效果，实现弹层的超出滚动效果，这样也就不用设置body的overflow-hidden和position-fixed了</h1>
    <div class="layer" id="layer">
      <div class="layer-box" id="layerBox">
        <div class="close" id="close">X</div>
        <!-- <div class="layer-cont">百度图片使用世界前沿的人工智能技术,为用户甄选海量的高清美图,用更流畅、更快捷、更精准的搜索体验,带你去发现多彩的世界。</div> -->
        <ul class="layer-list" id="layerList">
          <li>到顶</li>
          <li>第二行</li>
          <li>第三行</li>
          <li>第四行</li>
          <li>第五行</li>
          <li>第六行</li>

          <li>66666</li>

          <li>第一行</li>
          <li>第二行</li>
          <li>第三行</li>
          <li>第四行</li>
          <li>第五行</li>
          <li>第六行</li>
          <li>第一行</li>
          <li>第二行</li>
          <li>第三行</li>
          <li>第四行</li>
          <li>第五行</li>
          <li>第六行</li>

          <li>66666</li>

          <li>第一行</li>
          <li>第二行</li>
          <li>第三行</li>
          <li>第四行</li>
          <li>第五行</li>
          <li>到底</li>
        </ul>
        <div class="btns" style="display: none">
          <div class="btn-confirm">确认</div>
          <div class="btn-cancel">取消</div>
        </div>
      </div>
    </div>
    <div class="for-height">
      为了称高度 - 百度图片使用世界前沿的人工智能技术,为用户甄选海量的高清美图,用更流畅、更快捷、更精准的搜索体验,带你去发现多彩的世界。
      <img src="http://www.pptbz.com/pptpic/UploadFiles_6909/201203/2012031220134655.jpg" alt="">
      百度图片使用世界前沿的人工智能技术,为用户甄选海量的高清美图,用更流畅、更快捷、更精准的搜索体验,带你去发现多彩的世界。

      <img src="http://pic3.nipic.com/20090527/1242397_102231006_2.jpg" alt="">
      百度图片使用世界前沿的人工智能技术,为用户甄选海量的高清美图,用更流畅、更快捷、更精准的搜索体验,带你去发现多彩的世界。
      <img src="http://pic22.nipic.com/20120714/9622064_105642209176_2.jpg" alt="">
      百度图片使用世界前沿的人工智能技术,为用户甄选海量的高清美图,用更流畅、更快捷、更精准的搜索体验,带你去发现多彩的世界。
      为了称高度 - 百度图片使用世界前沿的人工智能技术,为用户甄选海量的高清美图,用更流畅、更快捷、更精准的搜索体验,带你去发现多彩的世界。
      <img src="http://www.pptbz.com/pptpic/UploadFiles_6909/201203/2012031220134655.jpg" alt="">
      百度图片使用世界前沿的人工智能技术,为用户甄选海量的高清美图,用更流畅、更快捷、更精准的搜索体验,带你去发现多彩的世界。
      <button id="btn">点击出弹层</button>
      <img src="http://pic3.nipic.com/20090527/1242397_102231006_2.jpg" alt="">
      百度图片使用世界前沿的人工智能技术,为用户甄选海量的高清美图,用更流畅、更快捷、更精准的搜索体验,带你去发现多彩的世界。
      <img src="http://pic22.nipic.com/20120714/9622064_105642209176_2.jpg" alt="">
      百度图片使用世界前沿的人工智能技术,为用户甄选海量的高清美图,用更流畅、更快捷、更精准的搜索体验,带你去发现多彩的世界。
    </div>
  </div>
  <script>
    /* 交互代码 */
    btn.onclick = function () {
      layer.style.display = 'block';
      //为了我的css能统一使用，这里偷个懒，加个行间样式，
      // 把之前做demo用的overflow滚动给禁掉，然后改了点别的样式
      layerBox.style.overflow = 'hidden';
      layerBox.style.paddingTop = 0;
      layerList.style.paddingTop = 0;
      layerList.style.paddingBottom = 0;
    }
    var closeBtn = document.getElementById('close');
    closeBtn.onclick = function () {
      console.log('?/*  */');
      layer.style.display = 'none';
      // 弹窗关闭后，可解除所有禁止 - 懒人就不写了
    }
    /* 禁掉所有的touchmove事件 */
    layer.addEventListener('touchmove', function (e) {
      e.preventDefault();
    }, false);
    /* 重新写touchmove效果 */
    var targetY = null,
      transH = 0,
      lastY = 0;
    layerBox.addEventListener('touchstart', function (e) {
      //这里简单的把整个layerBox的默认事件给禁止了，所以close的click事件就不起作用了。
      // 可以把结构再改改把close挪出来。或者js把close绕开：
      if (e.target != closeBtn) {
        e.preventDefault();
      }
      //clientY-客户区坐标Y 、pageY-页面坐标Y
      lastY = targetY = Math.floor(e.targetTouches[0].clientY);
    });
    layerBox.addEventListener('touchmove', function (e) {
      // 为了写这个，还得改动一下结构
      var NewTargetY = Math.floor(e.targetTouches[0].clientY), //本次移动时鼠标的位置，用于计算
        sTop = layerBox.scrollTop, //当前滚动的距离
        sH = layerBox.scrollHeight, //可滚动区域的高度
        lyBoxH = layerBox.clientHeight; //可视区域的高度
      if (NewTargetY - targetY > 0 && '鼠标方向向下滑-上翻效果') {
        transH += NewTargetY - lastY; // 先把这次鼠标滑动的距离计算出来，叠加给transH
        transH = transH >= 0 ? 0 : transH; //原本transH是负值，如果一直向上翻，就需要一直+正值，一旦正负相加抵消到>=0,说明翻到顶了，就直接赋值为顶，不再上翻。
      } else if (NewTargetY - targetY < 0 && '鼠标方向向上滑动-下拉效果') {
        transH -= lastY - NewTargetY; // 先把这次鼠标滑动的距离计算出来，叠减给transH
        transH = Math.abs(transH) > sH - lyBoxH ? -(sH - lyBoxH) : transH; //如果transH的绝对值大于可滚动的距离了，说明翻到底，则把可滚动区域翻到底的值赋给他。否则就一直下滚鼠标移动的距离
      }
      layerList.style.transform = `translateY(${ transH }px)`;
      lastY = NewTargetY;
    }, false);

    console.log(
      `
      大致想法就很笨重，就想layer的prevent Default效果了，所以他不再有滑动滚动的效果，我就用js的touch相关事件模拟出这个手势滑动，弹层可滚动区域的滚动效果。

      具体制作思路写在js注释上。

      不好的点就是没有原生滚动条那种效果，一点也不灵动，只能鼠标移动多少、可滚动区域挪动多少。

      但是这个做法我应用在项目中过，经得起测试的考验都。
    `
    )
  </script>
</body>

</html>